package dj.common.support.mvc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dj.common.annotation.QueryRequestBody;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <br>
 * <p>
 * -
 * </p>
 *
 * <br>
 *
 * @author ZJG
 * @version 1.0
 * @date 2021/12/7 下午4:00
 */
public class QueryRequestBodyMethodProcessor implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(QueryRequestBody.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest nativeWebRequest, WebDataBinderFactory binderFactory) {

        String name = methodParameter.getParameterAnnotation(QueryRequestBody.class).value();
        HttpServletRequest httpServletRequest = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        Map<String, String[]> map = httpServletRequest.getParameterMap();
        Class clazz = methodParameter.getParameterType();
        if (Collection.class.isAssignableFrom(clazz)) {
            // 集合泛型
            Type genericType = clazz.getComponentType();
            JSONArray jsonArray = new JSONArray();
            for (Map.Entry<String, String[]> entry : map.entrySet()) {
                String key = entry.getKey();
                String[] keys = key.split("\\.");
                if (Objects.equals(name, keys[0])) {
                    String[] values = entry.getValue();
                    for (String value : values) {
                        Map<String, Object> paramMap = new HashMap();
                        paramMap.put(keys[1], value);
                        jsonArray.add(paramMap);
                    }
                }
            }
            return JSON.parseArray(jsonArray.toJSONString(), genericType.getClass());
        }
        Map<String, Object> paramMap = new HashMap();
        for (Map.Entry<String, String[]> entry : map.entrySet()) {
            String key = entry.getKey();
            String[] keys = key.split("\\.");
            if (Objects.equals(name, keys[0])) {
                paramMap.put(keys[1], entry.getValue());
            }
        }
        return JSON.parseObject(JSONObject.toJSONString(paramMap), clazz);
    }

}


